package com.example.webSocket;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.example.pojo.ChatUser;
import com.example.pojo.MsgResult;
import com.fasterxml.jackson.annotation.JsonValue;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author xujiangtao
 */
@ServerEndpoint("/chat/{username}/{sex}")
@Component
@Slf4j
public class ChatEndPoint {


    Long id;
    /**
     * 保存所有客户端
     */
    public static Map<Long, ChatUser> clients = new ConcurrentHashMap<>();


    public List<String> getUsernames(){
        List<String> usernames = new ArrayList<>();
        for (Long clientId : clients.keySet()) {
            usernames.add(clients.get(clientId).getUsername());
        }
        return usernames;
    }

    public List<ChatUser> getChatUser(){
        List<ChatUser> chatUsers = new ArrayList<>();
        for (Long clientId : clients.keySet()) {
            chatUsers.add(clients.get(clientId));
        }
        return chatUsers;
    }
    /**
     * 连接时执行
     */
    @OnOpen
    public void onOpen(Session session,@PathParam("username") String username,@PathParam("sex") Integer sex){
        if (clients.size()>=2){
            try {
                session.close();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        Random random = new Random();
        long id = random.nextInt(9999);
        this.id = id;
        log.info("已经链接");
        clients.put(id,new ChatUser(id, username, sex,session));
        MsgResult res = new MsgResult();
        res.setFromName(username);
        res.setFromId(id);
        res.setFromSex(sex);
        res.setOnlineNums(clients.size());
        res.setChatUsers(getChatUser());
        sendMessage(res);
    }

    /**
     * 消息发送方法
     * @param msgResult
     */
    public void sendMessage(MsgResult msgResult)  {
        try {
            msgResult.setOnlineNums(clients.size());
            for (ChatUser item : clients.values()) {
//                if (item.getUserId().equals(msgResult.getToId())){
//                    try {
//                        item.getSession().getAsyncRemote().sendText(new ObjectMapper().writeValueAsString(msgResult));
//                    }catch (Exception e){
//                        item.getSession().close();
//                        clients.remove(id);
//                        log.error("消息发送异常，短开连接");
//                    }
//                    return;
//                }
//                //如果没有指定推送客户端或为大厅消息则全部发送
//                if (msgResult.getToId()==null){
                    try {
                        item.getSession().getAsyncRemote().sendText(new ObjectMapper().writeValueAsString(msgResult));
                    }catch (Exception e){
                        item.getSession().close();
                        clients.remove(id);
                        log.error("消息发送异常，短开连接");
                    }
//                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }

    }

    @OnClose
    public void onClose(){
        MsgResult res = new MsgResult();
        res.setFromName(clients.get(id).getUsername());
        res.setFromId(id);
        res.setFromSex(clients.get(id).getSex());
        clients.remove(id);
        res.setOnlineNums(clients.size());
        res.setChatUsers(getChatUser());
        sendMessage(res);
        log.warn("有链接关闭");
    }

    @OnMessage
    public void onMessage(String msg){
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            MsgResult msgResult = objectMapper.readValue(msg, MsgResult.class);
            log.info("接受到消息"+msgResult);
            sendMessage(msgResult);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

    }

    @OnError
    public void onError(Throwable error) throws IOException {
        clients.get(id).getSession().close();
        clients.remove(id);
        log.error(error.toString());
        log.error(error.getMessage());
    }

}
